/// @tags: SegTree Dij
#include <cctype>
#include <cstdio>
#include <cstring>
#include <queue>

namespace BlueQuantum {

typedef long long ll;

int const N = 1e5 + 5, M = 1e7 + 5, mod = 1e9 + 7;

template <typename T>
inline T &read(T &x) {
  x = 0;
  bool f = false;
  short ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = true;
    ch = getchar();
  }
  while (isdigit(ch)) x = x * 10 + (ch ^ '0'), ch = getchar();
  if (f) x = -x;
  return x;
}

struct Edge {
  int v, nxt, w;
} e[N << 1];

int S, T, n, m, e_cnt, tot;
int heads[N], vis[N], dis[N], texp[N + 25];
int ls[M], rs[M], hash[M], cnt[M];

inline void add(int u, int v, int w) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt, e[e_cnt].w = w;
}

int cmp(int l, int r, int a, int b) {
  if (l == r) return (hash[a] < hash[b]);
  int mid = (l + r) >> 1;
  if (hash[rs[a]] == hash[rs[b]]) return cmp(l, mid, ls[a], ls[b]);
  return cmp(mid + 1, r, rs[a], rs[b]);
}

struct Node {
  int id, dis;
  Node(int id = 0, int dis = 0) : id(id), dis(dis) {}
  inline bool operator<(Node const &rhs) const { return cmp(0, m + 20, rhs.dis, dis); }
};

std::priority_queue<Node> q;

inline void pushup(int l, int r, int x) {
  cnt[x] = cnt[ls[x]] + cnt[rs[x]];
  int mid = (l + r) >> 1;
  hash[x] = (1ll * hash[rs[x]] * texp[mid - l + 1] + hash[ls[x]]) % mod;
}

int find(int l, int r, int k, int x) {
  if (cnt[x] == r - l + 1) return -1;
  if (l == r) return l;
  int mid = (l + r) >> 1;
  if (mid < k) return find(mid + 1, r, k, rs[x]);
  int tmp = find(l, mid, k, ls[x]);
  if (tmp != -1) return tmp;
  return find(mid + 1, r, mid + 1, rs[x]);
}

int clear(int L, int R, int l, int r, int x) {
  if (L == l && R == r) return 0;
  int cur = ++tot;
  int mid = (l + r) >> 1;
  if (L > mid) ls[cur] = ls[x], rs[cur] = clear(L, R, mid + 1, r, rs[x]);
  else {
    if (R <= mid) ls[cur] = clear(L, R, l, mid, ls[x]), rs[cur] = rs[x];
    else {
      ls[cur] = clear(L, mid, l, mid, ls[x]);
      rs[cur] = clear(mid + 1, R, mid + 1, r, rs[x]);
    }
  }
  pushup(l, r, cur);
  return cur;
}

int set(int l, int r, int pos, int x) {
  int cur = ++tot;
  if (l == r) {
    cnt[cur] = hash[cur] = 1;
    return cur;
  }
  int mid = (l + r) >> 1;
  if (pos <= mid) ls[cur] = set(l, mid, pos, ls[x]), rs[cur] = rs[x];
  else
    ls[cur] = ls[x], rs[cur] = set(mid + 1, r, pos, rs[x]);
  pushup(l, r, cur);
  return cur;
}

inline int main() {
  read(n), read(m);
  texp[0] = 1;
  for (int i = 1; i <= N + 20; ++i) texp[i] = (texp[i - 1] << 1) % mod;
  for (int i = 1, s, t, x; i <= m; ++i) {
    read(s), read(t), read(x);
    add(s, t, x);
    add(t, s, x);
  }
  read(S), read(T);
  q.push(Node(S, 0));
  while (!q.empty()) {
    int u = q.top().id, d = q.top().dis;
    q.pop();
    if (dis[u] != d) continue;
    for (int i = heads[u], v; i; i = e[i].nxt) {
      int dst = find(0, N + 20, e[i].w, d);
      int dist = d;
      if (dst != e[i].w) dist = clear(e[i].w, dst - 1, 0, N + 20, dist);
      dist = set(0, N + 20, dst, dist);
      if (!dis[v = e[i].v]) q.push(Node(v, dis[v] = dist));
      else {
        if (cmp(0, N + 20, dist, dis[v])) { q.push(Node(v, dis[v] = dist)); }
      }
    }
  }
  printf("%d", hash[dis[T]]);
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("T2.in", "r", stdin);
  freopen("T2.out", "w", stdout);
#endif
#endif

  return BlueQuantum::main();
}
